#include "stdafx.h"
#include "types.h"
#include "Memory.h"

Memory::Memory(void)
{
}

Memory::~Memory(void)
{
}
u8 Memory::Read_memory_8(u16 address) {
    BankData ret = this->get_bank(address);
    return(ret.bank[address - ret.Mask]);
}
u16 Memory::Read_memory_16(u16 address) {
    BankData ret = this->get_bank(address);
    u16 retu;
    BigData tmp;
    tmp.B.B1 = ret.bank[address++ - ret.Mask];
    tmp.B.B0 = ret.bank[address - ret.Mask];
    retu = tmp.W;
    return(retu);
}
void Memory::Write_memory_8(u16 address, u8 value) {
    BankData ret = this->get_bank(address);
    ret.bank[address - ret.Mask] = value;
}
void Memory::Write_memory_16(u16 address, u16 value) {
    BankData ret = get_bank(address);
    BigData tmp;
    tmp.W = value;
    ret.bank[address++ - ret.Mask] = tmp.B.B1;
    ret.bank[address - ret.Mask] = tmp.B.B0;
}
bool Memory::check_bank(u16 address,u16 from,u16 to) {
    if (address >= from) {
        if (address <= to) {
         return true;
        }
        return false;
    }
    return false;
}
BankData Memory::get_bank(u16 address) {
    BankData ret;
    if (this->check_bank(address,0x0000,0x4000)) {
        ret.bank = this->RomBank0;
        ret.Mask = 0x0000;
    } else if (this->check_bank(address,0x4000,0x8000)) {
        ret.bank = this->SwitchableRomBank;
        ret.Mask = 0x4000;
    } else if (this->check_bank(address,0x8000,0xA000)) {
        ret.bank = this->VRAM;
        ret.Mask = 0x8000;
    } else if (this->check_bank(address,0xA000,0xC000)) {
        ret.bank = this->SwitchableRamBank;
        ret.Mask = 0xA000;
    } else if (this->check_bank(address,0xC000,0xE000)) {
        ret.bank = this->InternalRam;
        ret.Mask = 0xC000;
    } else if (this->check_bank(address,0xE000,0xFE00)) {
        ret.bank = this->OAM;
        ret.Mask = 0xE000;
    } else if (this->check_bank(address,0xFE00,0xFF00)) {
        ret.bank = this->Empty;
        ret.Mask = 0xFE00;
    } else if (this->check_bank(address,0xFF00,0xFF80)) {
        ret.bank = this->IO;
        ret.Mask = 0xFF00;
    } else if (this->check_bank(address,0xFF80,0xFFFE)) {
        ret.bank = this->Ram;
        ret.Mask = 0xFF80;
    } else if (address == 0xFFFF) {
        ret.bank = &this->InterruptRegister;
        ret.Mask = 0xFFFF;
    }
}
